home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Mathematics / Notebooks / SigProc2.0 / Packages / SignalProcessing / ObjectOriented / System.m < prev   
Encoding:
Text File  |  1992-08-18  |  15.9 KB  |  467 lines

  1. (*  :Title:    Signal Processing Systems  *)
  2.  
  3. (*  :Authors:    Brian Evans, James McClellan  *)
  4.  
  5. (*  :Summary:    To provide system properties and definitions a la Myers.  *)
  6.  
  7. (*  :Context:    SignalProcessing`ObjectOriented`System`  *)
  8.  
  9. (*  :PackageVersion:  2.7    *)
  10.  
  11. (*
  12.     :Copyright:    Copyright 1989-1991 by Brian L. Evans
  13.         Georgia Tech Research Corporation
  14.  
  15.     Permission to use, copy, modify, and distribute this software
  16.     and its documentation for any purpose and without fee is
  17.     hereby granted, provided that the above copyright notice
  18.     appear in all copies and that both that copyright notice and
  19.     this permission notice appear in supporting documentation,
  20.     and that the name of the Georgia Tech Research Corporation,
  21.     Georgia Tech, or Georgia Institute of Technology not be used
  22.     in advertising or publicity pertaining to distribution of the
  23.     software without specific, written prior permission.  Georgia
  24.     Tech makes no representations about the suitability of this
  25.     software for any purpose.  It is provided "as is" without
  26.     express or implied warranty.
  27.  *)
  28.  
  29. (*  :History:    *)
  30.  
  31. (*  :Keywords:    *)
  32.  
  33. (*
  34.     :Source:    Myers, Cory.  {Signal Representation for Symbolic and
  35.           Numeric Processing}.  M.I.T. Ph. D. Thesis.  August,
  36.           1986.  Appendix D.
  37.  
  38.         Covell, Michele.  {An Algorithm Design Environment for
  39.           Signal Processing}.  M.I.T. Ph. D. Thesis.  December,
  40.           1989.
  41.  *)
  42.  
  43. (*  :Warning:    *)
  44.  
  45. (*  :Mathematica Version:  1.2 or 2.0  *)
  46.  
  47. (*  :Limitation:  *)
  48.  
  49. (*
  50.     :Discussion:  Systems are defined in the same format as are mathematical
  51.           operators.  This format was chosen so that Mathematica's
  52.           powerful pattern matcher could be used without adjustment.
  53.           A full blown object representation was not needed since
  54.           no cacheing, fetching, dynamic properties, etc. are needed
  55.           as they are for signals.  That is, a z-transform operator
  56.           always exhibits linearity, and its properties do not
  57.           change.  In addition, systems are not instantiated as
  58.           are signals.
  59.  
  60.           Properties are attached to the operator AND its parameters.
  61.           If an operator can take optional arguments, then all flavors
  62.           of it must be separately installed by DefineSystem.
  63.  *)
  64.  
  65. (*
  66.     :Functions:    ASSOCIATIVE
  67.         ADDITIVE
  68.         COMMUTATIVE
  69.         CONTINUOUS
  70.         DefineSystem
  71.         DISCRETE
  72.         HOMOGENEOUS
  73.         LINEAR
  74.         LINEARPHASE
  75.         MEMORYLESS
  76.         MoveOperatorsToFront
  77.         SEPARABLE
  78.         SHIFTINVARIANT
  79.         SystemQ
  80.         ValidOperatorQ
  81.  *)
  82.  
  83.  
  84.  
  85. (*  B E G I N     P A C K A G E  *)
  86.  
  87. BeginPackage[ "SignalProcessing`ObjectOriented`System`",
  88.           "SignalProcessing`Support`FilterSupport`",
  89.           "SignalProcessing`Support`SigProc`",
  90.           "SignalProcessing`Support`SupCode`" ]
  91.  
  92.  
  93. If [ TrueQ[ $VersionNumber >= 2.0 ],
  94.      Off[ General::spell ];
  95.      Off[ General::spell1 ] ];
  96.  
  97.  
  98. (*  U S A G E     I N F O R M A T I O N  *)
  99.  
  100. ASSOCIATIVE::usage =
  101.     "ASSOCIATIVE is a system property. \
  102.     It also serves as a function. \
  103.     ASSOCIATIVE[system] returns True if the system is associative. \
  104.     Note that a system is a (parameterized) operator to which \
  105.     DefineSystem has attached properties. \
  106.     See also DefineSystem and SystemQ."
  107.  
  108. ADDITIVE::usage =
  109.     "ADDITIVE is a system property. \
  110.     An operator T is additive if T[x + y] = T[x] + T[y] for all x, y. \
  111.     It also serves as a function. \
  112.     ADDITIVE[system] returns True if the operator system is additive. \
  113.     Note that a system is a (parameterized) operator to which \
  114.     DefineSystem has attached properties. \
  115.     See also DefineSystem and SystemQ."
  116.  
  117. COMMUTATIVE::usage =
  118.     "COMMUTATIVE is a system property. \
  119.     It also serves as a function. \
  120.     COMMUTATIVE[system] returns True if the system is commutative. \
  121.     Note that a system is a (parameterized) operator to which \
  122.     DefineSystem has attached properties. \
  123.     See also DefineSystem and SystemQ."
  124.  
  125. CONTINUOUS::usage =
  126.     "CONTINUOUS is a system property. \
  127.     It also serves as a function. \
  128.     CONTINUOUS[system] returns True if the operator system only takes \
  129.     CONTINUOUS systems as arguments. \
  130.     Note that a system is a (parameterized) operator to which \
  131.     DefineSystem has attached properties. \
  132.     See also DefineSystem and SystemQ."
  133.  
  134. DefineSystem::usage =
  135.     "DefineSystem[operator, property1, property2, ...] will install \
  136.     the operator as a system. \
  137.     The properties property1, property2, ... are considered to be True \
  138.     for the operator. \
  139.     For example, if DefineSystem[Upsample[l, n], DISCRETE, LINEAR] \
  140.     is evaluated, Upsample will be added to the list of system operators \
  141.     SPsystems, and one of the four rules generated is \
  142.     CONTINUOUS[Shift[l,n]] := True. \
  143.     Note that CONTINUOUS[Shift] will have no meaning."
  144.  
  145. DISCRETE::usage =
  146.     "DISCRETE is a system property. \
  147.     It also serves as a function. \
  148.     DISCRETE[system] returns True if the system only accepts \
  149.     DISCRETE signals as arguments. \
  150.     Note that a system is a (parameterized) operator to which \
  151.     DefineSystem has attached properties. \
  152.     See also DefineSystem and SystemQ."
  153.  
  154. HOMOGENEOUS::usage =
  155.     "HOMOGENEOUS is a system property. \
  156.     An operator T is homogeneous if T[a x] = a T[x] if a is a scalar. \
  157.     It also serves as a function. \
  158.     HOMOGENEOUS[system] returns True if the system is homogeneous. \
  159.     Note that a system is a (parameterized) operator to which \
  160.     DefineSystem has attached properties. \
  161.     See also DefineSystem and SystemQ."
  162.  
  163. LINEAR::usage =
  164.     "LINEAR is a system property. \
  165.     A system is linear if it is both HOMOGENEOUS and ADDITIVE. \
  166.     It also serves as a function. \
  167.     LINEAR[system] returns True if the operator system is linear. \
  168.     Note that a system is a (parameterized) operator to which \
  169.     DefineSystem has attached properties. \
  170.     See also DefineSystem and SystemQ."
  171.  
  172. LINEARPHASE::usage =
  173.     "LINEARPHASE is a system property. \
  174.     A system exhibits linear phase if the phase component of its \
  175.     frequency response is an affine function of the frequency. \
  176.     It also serves a a function. \
  177.     LINEARPHASE[system] returns True if the system is memoryless. \
  178.     Note that a system is a (parameterized) operator to which \
  179.     DefineSystem has attached properties. \
  180.     See also DefineSystem and SystemQ."
  181.  
  182. MEMORYLESS::usage =
  183.     "MEMORYLESS is a system property. \
  184.     A system is memoryless if each output corresponding to a given input \
  185.     only depends on the input (and not past values of the input). \
  186.     It also serves a a function. \
  187.     MEMORYLESS[system] returns True if the system is memoryless. \
  188.     Note that a system is a (parameterized) operator to which \
  189.     DefineSystem has attached properties. \
  190.     A MEMORYLESS system with a single input is also SHIFTINVARIANT. \
  191.     See also DefineSystem and SystemQ."
  192.  
  193. MoveOperatorsToFront::usage =
  194.     "MoveOperatorsToFront[head_operator, signals, signals_to_move, \
  195.     operator_to_move] will move all operator_to_move operators \
  196.     contained in signals_to_move to the front of the expression formed \
  197.     by the head_operator operating on signals. \
  198.     For example, MoveOperatorsToFront[ Convolve[n], \
  199.     { x[n], Shift[2,n][y[n]] }, { Shift[2,n][y[n]] }, Shift ] \
  200.     yields Shift[2,n] [ Convolve[n] [ x[n], y[n] ] ]. \
  201.     This is a valid rewriting of the original expression. \
  202.     In this case, Convolve[n] [x[n], Shift[2,n][y[n]]]. \
  203.     This object is used in the system rewrite rules to rewrite \
  204.     properly an operator operating on more than one signal."
  205.  
  206. SEPARABLE::usage =
  207.     "SEPARABLE is a system property. \
  208.     It describes multidimensional systems that can decomposed \
  209.     into a cascade of one-dimensional operations. \
  210.     It also serves as a function. \
  211.     SEPARABLE[system] returns True if the \
  212.     operator system is separable. \
  213.     Note that a system is a (parameterized) operator to which \
  214.     DefineSystem has attached properties. \
  215.     See also DefineSystem and SystemQ."
  216.  
  217. SHIFTINVARIANT::usage =
  218.     "SHIFTINVARIANT is a system property. \
  219.     It means that a shift in the input causes the same shift \
  220.     in the output. \
  221.     It also serves as a function. \
  222.     SHIFTINVARIANT[system] returns True if the \
  223.     operator system is shift-invariant. \
  224.     Note that a system is a (parameterized) operator to which \
  225.     DefineSystem has attached properties. \
  226.     See also DefineSystem and SystemQ."
  227.  
  228. SystemProperties::usage =
  229.     "SystemProperties[system] will show the properties attached to \
  230.     of an operator or list of operators. \
  231.     Note that a system is a (parameterized) operator to which \
  232.     DefineSystem has attached properties. \
  233.     See also DefineSystem and SystemQ."
  234.  
  235. SPsystems::usage =
  236.     "SPsystems is a list of all recognized systems. \
  237.     Note that a system is a (parameterized) operator to which \
  238.     DefineSystem has attached properties. \
  239.     New ones can be defined by using DefineSystem."
  240.  
  241. SPproperties::usage =
  242.     "SPproperties contains a list of currently recognized \
  243.     system properties like LINEAR."
  244.  
  245. SystemQ::usage =
  246.     "SystemQ[system] will give True if system is in the SPsystems list, \
  247.     and False otherwise. \
  248.     Note that a system is a (parameterized) operator to which \
  249.     DefineSystem has attached properties. \
  250.     For example, by default, Shift[L, n] has been installed as a system, \
  251.     but Shift without the parameters has not."
  252.  
  253. ValidOperatorQ::usage =
  254.     "ValidOperatorQ[system, signal1, signal2, ...] will return True \
  255.     if every signal can be processed by the system. \
  256.     For example, False would be returned if system was only a \
  257.     discrete system and signal1 was a continuous signal."
  258.  
  259. (*  E N D     U S A G E     I N F O R M A T I O N  *)
  260.  
  261.  
  262. Begin[ "`Private`" ]
  263.  
  264.  
  265. (*  G L O B A L S  *)
  266.  
  267. SPsystems = {}
  268.  
  269. ValidOperatorQ::incompatible =
  270.   "The operator `` could not operate on one or more of these signals:  ``."
  271.  
  272. compatibilitycheck =
  273.   "`1`/: `2`[inputs__] := \
  274.      Message[ValidOperatorQ::incompatible, `3`, {inputs}] /; \
  275.      ! ValidOperatorQ[`3`, inputs]"
  276.  
  277. SPproperties =
  278.     {ASSOCIATIVE, ADDITIVE, COMMUTATIVE, CONTINUOUS, DISCRETE,
  279.      HOMOGENEOUS, LINEAR, LINEARPHASE, MEMORYLESS, SEPARABLE,
  280.      SHIFTINVARIANT}
  281.  
  282.  
  283. (*  S U P P O R T I N G     R O U T I N E S  *)
  284.  
  285. (*  DefineSystem --  generates Mathematica code for a system description     *)
  286. (*  abbreviations:  op for operator, prop for property, tsd for TagSetDelay  *)
  287.  
  288. (*
  289. defproperty[prop_, op_, headop_] :=
  290.     If [ AtomQ[op],
  291.          TagSetDelayed[op, prop[op], True],
  292.          TagSetDelayed[headop, prop[op], True];
  293.         TagSetDelayed[headop, prop[headop], True] ]
  294.  *)
  295.  
  296. (*  defproperty-- do not attach rules to Mathematica's built-in operators  *)
  297. defproperty[prop_Symbol, headop_, headop_] :=
  298.     Set[prop[headop], True] /;
  299.     SameQ[Context[headop], "System`"]
  300. defproperty[prop_Symbol, op_, headop_] :=
  301.     TagSetDelayed[prop, prop[op], True] /;
  302.     SameQ[Context[headop], "System`"]
  303. defproperty[prop_Symbol, op_, headop_] :=
  304.     TagSetDelayed[headop, prop[op], True]
  305.  
  306. SetAttributes[DefineSystem, HoldFirst]
  307.  
  308. DefineSystem[h_Symbol, properties__] :=
  309.     definesystem[ h, h, h, h, properties ]
  310. DefineSystem[h_[args__], properties__] :=
  311.     definesystem[ h,
  312.               Apply[h, Map[ToString, {args}]],
  313.               Apply[h, Map[GeneratePattern, {args}]],
  314.               h[args],
  315.               properties ]
  316.  
  317. definesystem[headop_, opstr_, op_, fullop_, properties__] :=
  318.     Block [    {proplist, protected, tsdattributes},
  319.  
  320.         protected = HasAttributes[headop, Protected];
  321.         If [ protected, UnprotectIt[headop] ];
  322.         proplist = ToList[properties];
  323.  
  324.         (*    Defining rules for compatibility checking between    *)
  325.         (*  signals and systems. This is only necessary when an    *)
  326.         (*  operator takes only continuous signals or discrete    *)
  327.         (*  signals as arguments.                *)
  328.         If [ Xor[MemberQ[proplist, DISCRETE],
  329.              MemberQ[proplist, CONTINUOUS]],
  330.              GenerateCode[
  331.             StringForm[compatibilitycheck, headop,
  332.                    InputForm[op], InputForm[fullop]] ] ];
  333.  
  334.         (*    TagSetDelayed needs to evaluate its arguments *)
  335.         (*  for the code generation to work.            *)
  336.         tsdattributes = Attributes[TagSetDelayed];
  337.         Unprotect[TagSetDelayed];
  338.         ClearAttributes[TagSetDelayed, {HoldFirst, HoldRest, HoldAll}];
  339.  
  340.         (*    Establishes a property as an Mathematica operator  *)
  341.         (*  which takes a system operator as an argument.     *)
  342.         (*  This allows statements like DISCRETE[Upsample] and   *)
  343.         (*  DISCRETE[Upsample[3,n]] to return True.         *)
  344.         If [ MemberQ[proplist, LINEAR],
  345.              Combine[proplist, {ADDITIVE, HOMOGENEOUS}] ];
  346.         Map [ defproperty[#1, op, headop]&, proplist ];
  347.  
  348.         (*  Return TagSetDelayed to its original evaluation settings  *)
  349.         SetAttributes[TagSetDelayed, tsdattributes];
  350.  
  351.         (*  Maintain a list of DSP operators  *)
  352.         Unprotect[SPsystems];
  353.         Combine[SPsystems, {opstr}];
  354.         Protect[SPsystems];
  355.  
  356.         (*  Restore protection of the operator if set beforehand  *)
  357.         If [ protected, ProtectIt[headop] ];
  358.  
  359.         headop ]
  360.  
  361. (*  MoveOperatorToFront  *)
  362. MoveOperatorsToFront[ op_, siglist_, sigleftlist_, optomove_ ] :=
  363.     Block [    {numops, opindex, oplist, result},
  364.         oplist = Map[OperatorInOperExpr, sigleftlist];
  365.         numops = Length[oplist];
  366.         result = Apply[op, Map[SignalsInOperExpr[#, optomove]&, siglist]];
  367.         For [ opindex = 1, opindex <= numops, opindex++,
  368.               result = oplist[[opindex]] [ result ] ];
  369.         result ]
  370.  
  371. (*  SystemQ  *)
  372. SystemQ[op_[args__]] := SystemQ[op]
  373. SystemQ[op_] := MemberQ[SPsystems, op] /; AtomQ[op]
  374.  
  375. (*  ValidOperatorQ  *)
  376. ValidOperatorQ[system_, signal_] :=
  377.     Which [ TrueQ[ DISCRETE[signal] ],
  378.           TrueQ[ DISCRETE[system] ],
  379.         TrueQ[ CONTINUOUS[signal] ],
  380.           TrueQ[ CONTINUOUS[system] ],
  381.         True,
  382.           True ]
  383. ValidOperatorQ[system_, signal1_, signal__] :=
  384.     And[ValidOperatorQ[system, signal1], ValidOperatorQ[system, signal]]
  385.  
  386.  
  387. (*  R E C O G N I Z E D     S Y S T E M S  *)
  388.  
  389. (*  Standard Mathematica operators  *)
  390.  
  391. DefineSystem[Plus, COMMUTATIVE, CONTINUOUS, DISCRETE, MEMORYLESS]
  392. DefineSystem[Times, COMMUTATIVE, CONTINUOUS, DISCRETE, LINEAR, MEMORYLESS]
  393.  
  394. (*  Operators in the signal processing packages  *)
  395.  
  396. DefineSystem[CircularShift[n0, N, n], DISCRETE, LINEAR, SHIFTINVARIANT]
  397. DefineSystem[Conjugate,
  398.          ADDITIVE, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT]
  399. DefineSystem[CConvolve[t],
  400.          ASSOCIATIVE, COMMUTATIVE, CONTINUOUS, LINEAR, SHIFTINVARIANT]
  401. DefineSystem[Convolve[n],
  402.          ASSOCIATIVE, COMMUTATIVE, DISCRETE, LINEAR, SHIFTINVARIANT]
  403. DefineSystem[Difference[k, n], DISCRETE, LINEAR, SEPARABLE]
  404. DefineSystem[Divide, CONTINUOUS, DISCRETE, MEMORYLESS]
  405. DefineSystem[Downsample[m, n], DISCRETE, LINEAR ]
  406. Downsample/: SEPARABLE[ Downsample[m_, n_List] ] := DiagonalMatrixQ[m]
  407. DefineSystem[DFT[l, n, k], DISCRETE, LINEAR]
  408. DefineSystem[DTFT[n, w], DISCRETE, LINEAR]
  409. DefineSystem[FIR[n, coeffs], DISCRETE, LINEAR, SHIFTINVARIANT]
  410. DefineSystem[FT[t, w], CONTINUOUS, LINEAR]
  411. DefineSystem[IIR[n, coeffs], DISCRETE, LINEAR, SHIFTINVARIANT]
  412. DefineSystem[Im,
  413.          ADDITIVE, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT]
  414. DefineSystem[Interleave[n], DISCRETE]
  415. DefineSystem[InvDFT[l, k, n], DISCRETE, LINEAR]
  416. DefineSystem[InvDTFT[w, n], DISCRETE, LINEAR]
  417. DefineSystem[InvFT[w, t], CONTINUOUS, LINEAR]
  418. DefineSystem[InvL[s, t], CONTINUOUS, LINEAR]
  419. DefineSystem[InvZ[z, n], DISCRETE, LINEAR]
  420. DefineSystem[L[t, s], CONTINUOUS, LINEAR]
  421. DefineSystem[Periodic[k, n], CONTINUOUS, DISCRETE, SEPARABLE]
  422. DefineSystem[PolyphaseDownsample[m, h, n], DISCRETE, LINEAR]
  423. DefineSystem[PolyphaseUpsample[l, h, n], DISCRETE, LINEAR]
  424. DefineSystem[Re,
  425.          ADDITIVE, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT]
  426. (* DefineSystem[Reciprocal, CONTINUOUS, DISCRETE, MEMORYLESS, SHIFTINVARIANT] *)
  427. DefineSystem[Rev[n], CONTINUOUS, DISCRETE, LINEAR, SEPARABLE]
  428. DefineSystem[ScaleAxis[l, w], CONTINUOUS, LINEAR, SEPARABLE]
  429. DefineSystem[Shift[l, n],
  430.          CONTINUOUS, DISCRETE, LINEAR, SEPARABLE, SHIFTINVARIANT]
  431. DefineSystem[Subtract, CONTINUOUS, DISCRETE, MEMORYLESS]
  432. DefineSystem[Summation[i, ibeg, iend, inc], DISCRETE, LINEAR]
  433. DefineSystem[Upsample[l, n], DISCRETE, LINEAR]
  434. Upsample/: SEPARABLE[ Upsample[m_, n_List] ] := DiagonalMatrixQ[m]
  435. DefineSystem[Z[n, z], DISCRETE, LINEAR]
  436.  
  437. (*  Retrive the properties attached to an operator  *)
  438.  
  439. SetAttributes[SystemProperties, Listable]
  440.  
  441. SystemProperties[op_] := ( op -> Select[ SPproperties, TrueQ[#1[op]]& ] )
  442.  
  443.  
  444. (*  E N D     P A C K A G E  *)
  445.  
  446. End[]
  447. EndPackage[]
  448.  
  449. If [ TrueQ[ $VersionNumber >= 2.0 ],
  450.      On[ General::spell ];
  451.      On[ General::spell1 ] ];
  452.  
  453.  
  454. (*  W R I T E     P R O T E C T I O N  *)
  455.  
  456. Block [    {newfuns},
  457.     newfuns = { DefineSystem,    MoveOperatorsToFront,    SystemQ,
  458.             SystemProperties,    ValidOperatorQ };
  459.     Combine[ SPfunctions, newfuns ];
  460.     Apply[ Protect, newfuns ] ]
  461.  
  462.  
  463. (*  E N D I N G     M E S S A G E  *)
  464.  
  465. Print["System definitions have been loaded."]
  466. Null
  467.